package com.utils.httpclient;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Form;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j; 

@Slf4j
public class HttpUtil2dataexchange {
    public static final String ACTIVATION_CALLBACK_URL = "http://mreport.kyhddsp.com/";

    public static final int CONNECT_TIMEOUT = 2000;
    public static final int SOCKET_TIMEOUT = 3000;
    public static final int GET = 0;
    public static final int POST = 1;
    
	static Executor executor;
    
    static{
    		try {
                HttpClient httpClient = HttpClients.custom()
                        .setSSLSocketFactory(new SSLConnectionSocketFactory(SSLContexts.custom()
                                        .loadTrustMaterial(null, new TrustSelfSignedStrategy())
                                        .build()
                                )
                        ).disableRedirectHandling().build();//.build();

                executor = Executor.newInstance(httpClient);
            }catch (Exception e){
    		    e.printStackTrace();
            }
    }


    public static final JSONObject getJsonParamsFromUrl(String url){
        JSONObject ret = new JSONObject();
        if(url == null) return ret;
        try {
            if(url.toLowerCase().indexOf("http://") == -1) url = ACTIVATION_CALLBACK_URL+"?"+url;
            URIBuilder builder = new URIBuilder(url);
            List<NameValuePair> nvlist = builder.getQueryParams();
            for(NameValuePair nv:nvlist){
                ret.put(nv.getName(),nv.getValue());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return ret;
    }

    public static final String decodeURL(String param){
        if(param == null) return null;
        try{
            return URLDecoder.decode(param,"UTF-8");
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static final String encodeURL(String param){
        if(param == null) return null;
        try{
            return URLEncoder.encode(param,"UTF-8");
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    public static final String decodeAndToUpperCase(String param){
        String ret  = HttpUtil2dataexchange.decodeURL(param);
        ret = ret==null?"":ret.toUpperCase();
        return ret;
    }
    
    public static final JSONObject getJSON(String url){
        return getJSON(url,null,null,GET);
    }

    public static final JSONObject getJSON(String url,HashMap<String,String> params){
        return getJSON(url,params,null,GET);
    }

    public static final JSONObject getJSON(String url,HashMap<String,String> params,HashMap<String,String> headers){
        return getJSON(url,params,headers,GET);
    }

    public static final JSONObject postJSON(String url,HashMap<String,String> params){
        return getJSON(url,params,null,POST);
    }

    public static final JSONObject postJSON(String url,HashMap<String,String> params,HashMap<String,String> headers){
        return getJSON(url,params,headers,POST);
    }

    public static final JSONObject getJSON(String url,HashMap<String,String> params,HashMap<String,String> headers,int method){
    	 JSONObject json = null;
         try {
             HttpResponse response = null;
             if(method == GET) response = get(url, params, headers);
             else if(method == POST) response = post(url, params, headers);

             if(response == null){
                 throw new Exception("request error");
             }

             if (response.getStatusLine().getStatusCode() == 200) {
                 HttpEntity entity = response.getEntity();
                 byte[] b = EntityUtils.toByteArray(entity);
                 String res = new String(b);
                 log.info("get_{}({}?{}) -->result:{}",method,url,params,res);
                 res = res==null||res.trim().length()<1?"{}":res;
                 if("OK".equalsIgnoreCase(res)) {
                 	res = "{\"result\":\"OK\"}"; //第三方检测用
                 }
                 json = JSONObject.parseObject(res);
             }else{
                 json = new JSONObject();
                 json.put("code",response.getStatusLine().getStatusCode());
                 HttpEntity entity = response.getEntity();
                 byte[] b = EntityUtils.toByteArray(entity);
                 String res = new String(b);
                 json.put("response",res);
                 log.info("get_{}({}?{}) code is {} -->result:{}",method,url,params,response.getStatusLine().getStatusCode(),res);
             }
         }catch (Exception e) {
//             e.printStackTrace();
//             json = new JSONObject();
//             json.put("code", 500);
//             json.put("exception", e.getMessage());
             log.error("retry one times,getJSON exception:{} url:{}?{}", e.getMessage(),url,params);
         	try {
                 HttpResponse response = null;
                 if(method == GET) response = get(url, params, headers);
                 else if(method == POST) response = post(url, params, headers);

                 if(response == null){
                     throw new Exception("request error");
                 }

                 if (response.getStatusLine().getStatusCode() == 200) {
                     HttpEntity entity = response.getEntity();
                     byte[] b = EntityUtils.toByteArray(entity);
                     String res = new String(b);
                     log.info("get_{}({}?{}) -->result:{}",method,url,params,res);
                     res = res==null||res.trim().length()<1?"{}":res;
                     json = JSONObject.parseObject(res);
                 }else{
                     json = new JSONObject();
                     json.put("code",response.getStatusLine().getStatusCode());
                     HttpEntity entity = response.getEntity();
                     byte[] b = EntityUtils.toByteArray(entity);
                     String res = new String(b);
                     json.put("response",res);
                     log.info("get_{}({}?{}) code is {} -->result:{}",method,url,params,response.getStatusLine().getStatusCode(),res);
                 }
             }catch (Exception e1) {
                 e1.printStackTrace();
                 json = new JSONObject();
                 json.put("code", 500);
                 json.put("exception", e1.getMessage());
                 log.error("getJSON exception:{} url:{}?{}", e1.getMessage(),url,params);
             }
             
         }
         return json;
    }

    public static final String getContent(String url){
        return getContent(url,null,null);
    }

    public static final String getContent(String url,HashMap<String,String> params){
        return getContent(url,params,null);
    }

    public static final String getContent(String url,HashMap<String,String> params,HashMap<String,String> headers){
        try {
            HttpResponse response = get(url, params, headers);
            HttpEntity entity = response.getEntity();
            byte[] b = EntityUtils.toByteArray(entity);
            String ret = new String(b);
            log.info("getContent({}?{}) result:{}",url,params,ret);
            return ret;
        }catch (Exception e) {
            return e.getMessage();
        }
    }

    static final HttpResponse get(String url,HashMap<String,String> params,HashMap<String,String> headers){
        try {
            URIBuilder builder = new URIBuilder(url);
            if(params != null) {
                for (String key : params.keySet()) {
                    builder.addParameter(key, params.get(key));
                }
            }

            String _url = builder.toString();

            Request request = Request.Get(_url)
                    .connectTimeout(CONNECT_TIMEOUT)
                    .socketTimeout(SOCKET_TIMEOUT);

            if(headers != null) {
                for (String key : headers.keySet()) {
                    request.setHeader(key, headers.get(key));
                }
            }
            return executor.execute(request).returnResponse();
        }catch (Exception e){
            log.error("get({}?{}) error:{}",url,params,e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    static final HttpResponse post(String uri,HashMap<String,String> params,HashMap<String,String> headers){
        try {

            Request request = Request.Post(uri)
                    .connectTimeout(CONNECT_TIMEOUT)
                    .socketTimeout(SOCKET_TIMEOUT);

            Form form = Form.form();
            if(params != null) {
                for (String key : params.keySet()) {
                    form.add(key, params.get(key));
                }
            }
            request = request.bodyForm(form.build());

            if(headers != null) {
                for (String key : headers.keySet()) {
                    request.setHeader(key, headers.get(key));
                }
            }
            return executor.execute(request).returnResponse();
        }catch (Exception e){
            log.error("post({}?{}) error:{}",uri,params,e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
}
